/**
 * Notes: 服务器API请求助手 (完全替代云函数)
 * Ver : WeCollege Server API 1.0.0
 * Date: 2025-01-27
 * Description: 替代cloud_helper.js，使用自建服务器API
 */

const helper = require('./helper.js');
const dataHelper = require('./data_helper.js');
const cacheHelper = require('./cache_helper.js');
const constants = require('../comm/constants.js');
const pageHelper = require('../helper/page_helper.js');
const timeHelper = require('../helper/time_helper.js');
const apiConfig = require('../setting/api_config.js');

// 响应状态码
const CODE = {
  SUCC: 200,
  SVR: 500,        // 服务器错误  
  LOGIC: 1600,     // 逻辑错误 
  DATA: 1301,      // 数据校验错误 
  HEADER: 1302,    // header 校验错误  
  UNAUTHORIZED: 401, // 未授权
  FORBIDDEN: 403,   // 禁止访问
  NOT_FOUND: 404,   // 资源不存在

  ADMIN_ERROR: 2401, // 管理员错误
  WORK_ERROR: 2501   // 工作人员错误
};

/**
 * 异步提交请求 (不显示loading)
 * @param {string} route - 路由
 * @param {object} params - 参数
 * @param {object} options - 选项
 * @returns {Promise} 请求结果
 */
function callServerSumbitAsync(route, params = {}, options) {
  if (!helper.isDefined(options)) options = { hint: false };
  if (!helper.isDefined(options.hint)) options.hint = false;
  return callServer(route, params, options);
}

/**
 * 提交请求 (显示loading)
 * @param {string} route - 路由
 * @param {object} params - 参数
 * @param {object} options - 选项
 * @returns {Promise} 请求结果
 */
async function callServerSumbit(route, params = {}, options = { title: '提交中...' }) {
  if (!helper.isDefined(options)) options = { title: '提交中..' };
  if (!helper.isDefined(options.title)) options.title = '提交中..';
  return await callServer(route, params, options);
}

/**
 * 获取数据请求
 * @param {string} route - 路由
 * @param {object} params - 参数
 * @param {object} options - 选项
 * @returns {Promise} 数据结果
 */
async function callServerData(route, params = {}, options) {
  if (!helper.isDefined(options)) options = { title: '加载中..' };
  if (!helper.isDefined(options.title)) options.title = '加载中..';
  
  let result = await callServer(route, params, options).catch(err => {
    return null;
  });

  if (result && helper.isDefined(result.data)) {
    result = result.data;
    if (Array.isArray(result)) {
      // 数组处理
    } else if (Object.keys(result).length == 0) {
      result = null; // 对象处理
    }
  }
  return result;
}

/**
 * 核心服务器请求方法
 * @param {string} route - 路由
 * @param {object} params - 参数
 * @param {object} options - 选项
 * @returns {Promise} 请求结果
 */
function callServer(route, params = {}, options) {
  let title = '加载中';
  let hint = true;

  // 标题
  if (helper.isDefined(options) && helper.isDefined(options.title))
    title = options.title;

  if (helper.isDefined(options) && helper.isDefined(options.hint))
    hint = options.hint;

  if (hint) {
    if (title == 'bar')
      wx.showNavigationBarLoading();
    else
      wx.showLoading({
        title: title,
        mask: true
      });
  }

  // 获取token
  let token = '';
  let headers = { ...apiConfig.DEFAULT_HEADERS };

  // 管理员token
  if (route.indexOf('admin/') > -1) {
    let admin = cacheHelper.get(constants.CACHE_ADMIN);
    if (admin && admin.token) {
      token = admin.token;
      headers['Authorization'] = `Bearer ${token}`;
    }
  } else if (route.indexOf('work/') > -1) {
    let work = cacheHelper.get(constants.CACHE_WORK);
    if (work && work.token) {
      token = work.token;
      headers['Authorization'] = `Bearer ${token}`;
    }
  } else {
    // 正常用户
    let user = cacheHelper.get(constants.CACHE_TOKEN);
    if (user && user.id) {
      token = user.id;
      headers['Authorization'] = `Bearer ${token}`;
    }
  }

  return new Promise(function (resolve, reject) {
    // 构建请求URL
    const baseURL = apiConfig.baseURL;
    const url = `${baseURL}/api/${route}`;

    // 确定请求方法
    const method = _getHttpMethod(route);

    // 构建请求数据
    let requestData = { ...params };
    if (method === 'GET') {
      // GET请求参数放在URL中
      const queryString = _buildQueryString(requestData);
      const finalUrl = queryString ? `${url}?${queryString}` : url;
      
      wx.request({
        url: finalUrl,
        method: 'GET',
        header: headers,
        success: function (res) {
          _handleResponse(res, resolve, reject, hint);
        },
        fail: function (err) {
          _handleError(err, reject, hint);
        },
        complete: function () {
          _hideLoading(hint, title);
        }
      });
    } else {
      // POST/PUT/DELETE请求
      wx.request({
        url: url,
        method: method,
        data: requestData,
        header: headers,
        success: function (res) {
          _handleResponse(res, resolve, reject, hint);
        },
        fail: function (err) {
          _handleError(err, reject, hint);
        },
        complete: function () {
          _hideLoading(hint, title);
        }
      });
    }
  });
}

/**
 * 数据列表请求 (替代云函数的dataList)
 * @param {object} that - 页面this对象
 * @param {string} listName - 列表数据名称
 * @param {string} route - 路由
 * @param {object} params - 参数
 * @param {object} options - 选项
 * @param {boolean} isReverse - 是否反向插入
 */
async function dataList(that, listName, route, params, options, isReverse = false) {
  console.log('dataList begin');

  if (!helper.isDefined(that.data[listName]) || !that.data[listName]) {
    let data = {};
    data[listName] = {
      page: 1,
      size: 20,
      list: [],
      count: 0,
      total: 0,
      oldTotal: 0
    };
    that.setData(data);
  }

  if (!helper.isDefined(params.isTotal))
    params.isTotal = true;

  let page = params.page;
  let count = that.data[listName].count;
  if (page > 1 && page > count) {
    wx.showToast({
      duration: 500,
      icon: 'none',
      title: '没有更多数据了',
    });
    return;
  }

  // 清理undefined参数
  for (let key in params) {
    if (!helper.isDefined(params[key]))
      delete params[key];
  }

  let oldTotal = 0;
  if (that.data[listName] && that.data[listName].total)
    oldTotal = that.data[listName].total;
  params.oldTotal = oldTotal;

  // 服务器API调用
  await callServer(route, params, options).then(function (res) {
    console.log('server request begin');

    let dataList = res.data;
    let tList = that.data[listName].list;

    if (dataList.page == 1) {
      tList = res.data.list;
    } else if (dataList.page > that.data[listName].page) {
      if (isReverse)
        tList = res.data.list.concat(tList);
      else
        tList = tList.concat(res.data.list);
    } else
      return;

    dataList.list = tList;
    let listData = {};
    listData[listName] = dataList;

    that.setData(listData);

    console.log('server request END');
  }).catch(err => {
    console.log(err);
  });

  console.log('dataList END');
}

/**
 * 上传单个图片到服务器
 * @param {string} filePath - 本地文件路径
 * @param {string} dir - 目录
 * @param {string} id - ID
 * @param {boolean} isCheck - 是否检查内容
 * @returns {Promise<string>} 上传后的URL
 */
async function uploadImageOne(filePath, dir = 'images', id = '', isCheck = true) {
  if (!filePath) return '';

  // 内容检查
  if (isCheck) {
    wx.showLoading({
      title: '图片校验中',
      mask: true
    });
    
    // 这里可以添加图片内容检查逻辑
    // let check = await contentCheckHelper.imgCheck(filePath);
    // if (!check) {
    //   wx.hideLoading();
    //   return pageHelper.showModal('不合适的图片, 请重新上传', '温馨提示');
    // }
    
    wx.hideLoading();
  }

  return new Promise((resolve, reject) => {
    const uploadUrl = `${apiConfig.baseURL}/api/upload/image`;
    
    // 获取用户token
    let token = '';
    let user = cacheHelper.get(constants.CACHE_TOKEN);
    if (user && user.id) {
      token = user.id;
    }

    wx.uploadFile({
      url: uploadUrl,
      filePath: filePath,
      name: 'file',
      formData: {
        dir: dir,
        id: id || timeHelper.time('YMD')
      },
      header: {
        'Authorization': token ? `Bearer ${token}` : ''
      },
      success: function (res) {
        try {
          const data = JSON.parse(res.data);
          if (data.code === 200) {
            resolve(data.data.url || data.data.fileUrl || '');
          } else {
            reject(new Error(data.message || '上传失败'));
          }
        } catch (e) {
          reject(new Error('上传响应解析失败'));
        }
      },
      fail: function (err) {
        reject(err);
      }
    });
  });
}

/**
 * 批量上传图片
 * @param {Array} imgList - 图片列表
 * @param {string} dir - 目录
 * @param {string} id - ID
 * @param {string} prefix - 前缀
 * @returns {Promise<Array>} 上传后的URL列表
 */
async function uploadImages(imgList, dir, id, prefix = '') {
  if (!imgList || imgList.length === 0) return [];

  if (prefix && !prefix.endsWith('_')) prefix += '_';
  if (!id) id = timeHelper.time('YMD');

  for (let i = 0; i < imgList.length; i++) {
    let filePath = imgList[i];
    
    // 是否为临时文件
    if (filePath && (filePath.includes('tmp') || filePath.includes('temp') || filePath.includes('wxfile'))) {
      try {
        const uploadedUrl = await uploadImageOne(filePath, dir, id, false);
        imgList[i] = uploadedUrl;
      } catch (error) {
        console.error('图片上传失败:', error);
        // 上传失败时保持原路径或清空
        // imgList[i] = '';
      }
    }
  }

  return imgList;
}

// ==================== 私有方法 ====================

/**
 * 根据路由确定HTTP方法
 * @param {string} route - 路由
 * @returns {string} HTTP方法
 */
function _getHttpMethod(route) {
  // 根据路由规则确定HTTP方法
  if (route.includes('/insert') || route.includes('/add') || route.includes('/login') || route.includes('/register')) {
    return 'POST';
  } else if (route.includes('/edit') || route.includes('/update')) {
    return 'PUT';
  } else if (route.includes('/del') || route.includes('/delete')) {
    return 'DELETE';
  } else {
    return 'GET';
  }
}

/**
 * 构建查询字符串
 * @param {object} params - 参数对象
 * @returns {string} 查询字符串
 */
function _buildQueryString(params) {
  const queryParts = [];
  for (const key in params) {
    if (params.hasOwnProperty(key) && params[key] !== undefined && params[key] !== null) {
      queryParts.push(`${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`);
    }
  }
  return queryParts.join('&');
}

/**
 * 处理响应
 * @param {object} res - 响应对象
 * @param {function} resolve - 成功回调
 * @param {function} reject - 失败回调
 * @param {boolean} hint - 是否显示提示
 */
function _handleResponse(res, resolve, reject, hint) {
  console.log('API Response:', res);

  // 处理HTTP状态码
  if (res.statusCode !== 200) {
    const error = {
      code: res.statusCode,
      msg: `HTTP ${res.statusCode} 错误`
    };
    _showError(error, hint);
    reject(error);
    return;
  }

  // 处理响应数据
  let result = res.data;
  
  // 如果响应是字符串，尝试解析JSON
  if (typeof result === 'string') {
    try {
      result = JSON.parse(result);
    } catch (e) {
      console.error('JSON解析失败:', e);
      const error = { code: -1, msg: '响应数据格式错误' };
      _showError(error, hint);
      reject(error);
      return;
    }
  }

  // 处理业务状态码
  if (result.code === CODE.LOGIC || result.code === CODE.DATA) {
    // 逻辑错误&数据校验错误
    if (hint) {
      wx.showModal({
        title: '温馨提示',
        content: result.message || result.msg || '操作失败',
        showCancel: false
      });
    }
    reject(result);
    return;
  } else if (result.code === CODE.UNAUTHORIZED || result.code === CODE.ADMIN_ERROR) {
    // 未授权或管理员登录错误
    _handleUnauthorized();
    return;
  } else if (result.code === CODE.WORK_ERROR) {
    // 工作人员登录错误
    wx.reLaunch({
      url: pageHelper.fmtURLByPID('/pages/work/index/login/work_login'),
    });
    return;
  } else if (result.code !== CODE.SUCC && result.code !== 200) {
    // 其他错误
    if (hint) {
      wx.showModal({
        title: '温馨提示',
        content: result.message || result.msg || '系统开小差了，请稍后重试',
        showCancel: false
      });
    }
    reject(result);
    return;
  }

  // 成功响应
  resolve(result);
}

/**
 * 处理请求错误
 * @param {object} err - 错误对象
 * @param {function} reject - 失败回调
 * @param {boolean} hint - 是否显示提示
 */
function _handleError(err, reject, hint) {
  console.error('API Error:', err);
  
  if (hint) {
    let content = '网络故障，请稍后重试';
    
    if (err.errMsg) {
      if (err.errMsg.includes('timeout')) {
        content = '请求超时，请检查网络连接';
      } else if (err.errMsg.includes('fail')) {
        content = '网络连接失败，请检查网络设置';
      }
    }
    
    wx.showModal({
      title: '网络错误',
      content: content,
      showCancel: false
    });
  }
  
  reject({ code: -1, msg: err.errMsg || '网络错误' });
}

/**
 * 显示错误信息
 * @param {object} error - 错误对象
 * @param {boolean} hint - 是否显示提示
 */
function _showError(error, hint) {
  if (hint) {
    wx.showModal({
      title: '温馨提示',
      content: error.msg || error.message || '操作失败',
      showCancel: false
    });
  }
}

/**
 * 处理未授权错误
 */
function _handleUnauthorized() {
  // 清除token
  cacheHelper.remove(constants.CACHE_TOKEN);
  cacheHelper.remove(constants.CACHE_ADMIN);
  
  // 跳转到登录页面
  const currentPages = getCurrentPages();
  const currentPage = currentPages[currentPages.length - 1];
  const currentRoute = currentPage ? currentPage.route : '';
  
  if (currentRoute.includes('admin')) {
    wx.reLaunch({
      url: pageHelper.fmtURLByPID('/pages/admin/index/login/admin_login'),
    });
  } else {
    wx.showModal({
      title: '登录过期',
      content: '登录状态已过期，请重新登录',
      confirmText: '重新登录',
      showCancel: false,
      success: function() {
        wx.reLaunch({
          url: pageHelper.fmtURLByPID('/pages/my/index/my_index'),
        });
      }
    });
  }
}

/**
 * 隐藏loading
 * @param {boolean} hint - 是否显示提示
 * @param {string} title - 标题
 */
function _hideLoading(hint, title) {
  if (hint) {
    if (title == 'bar')
      wx.hideNavigationBarLoading();
    else
      wx.hideLoading();
  }
}

module.exports = {
  CODE,
  dataList,
  callServer,
  callServerSumbit,
  callServerData,
  callServerSumbitAsync,
  uploadImages,
  uploadImageOne,
  
  // 兼容原cloud_helper的方法名
  callCloud: callServer,
  callCloudSumbit: callServerSumbit,
  callCloudData: callServerData,
  callCloudSumbitAsync: callServerSumbitAsync,
  transTempPics: uploadImages,
  transTempPicOne: uploadImageOne
};